using System;
using System.Collections;
using System.IO;
using Cinemachine;
using com.yoozoo.gta.Extension;
using UnityEngine;
using UnityEngine.Playables;
using XLua;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got;
using Yoozoo.UI;
using Yoozoo.UI.YGUI;

namespace Gameplay.PVE
{
    //用于打包lua调用c#的高消耗的方法
    public class RpgWrap
    {
        public static bool MoveToTarget(Transform mover,Transform target,float speed)
        {
            var targetPosition = target.position;
            return MoveToTargetPosition(mover, targetPosition, speed);
        }

        public static bool MoveToTargetByVector3(Vector3 startPosition, Transform target, float speed, out Vector3 newPosition)
        {
            var targetPosition = target.position;
            var diff = targetPosition - startPosition;
            var distanceSqr = diff.sqrMagnitude;
            if (distanceSqr <= speed * speed)
            {
                newPosition = targetPosition;
                return true;
            }
            else
            {
                var moveAmount = diff.normalized * speed;
                newPosition = startPosition + moveAmount;
                return false;
            }
        }


        public static bool MoveToTargetPosition(Transform mover, Vector3 targetPosition, float speed)
        {
            var startPosition = mover.position;
            var diff = targetPosition - startPosition;
            var distanceSqr = diff.sqrMagnitude;
            if (distanceSqr <= speed * speed)
            {
                mover.position = targetPosition;
                mover.forward = diff;
                return true;
            }
            else
            {
                var moveAmount = diff.normalized * speed;
                mover.position = startPosition + moveAmount;
                mover.forward = diff;
                return false;
            }
        }

        public static bool MoveToTargetPositionBySpecificDirection(Transform mover,Vector3 targetPosition,Vector3 speed,out Vector3 newPosition)
        {
            var startPosition = mover.position;
            var diff = targetPosition - startPosition;
            var distanceSqr = diff.sqrMagnitude;
            var speedValue = speed.sqrMagnitude;
            if (distanceSqr <= speedValue)
            {
                newPosition = targetPosition;
                mover.position = newPosition;
                mover.forward = speed;
                return true;
            }
            else
            {
                newPosition = startPosition + speed;
                mover.position = newPosition;
                mover.forward = speed;
                return false;
            }
        }

        public static void SetTransformDataWithParent(Transform transform, Vector3 position, Vector3 forward, float scale,
            Transform parent = null)
        {
            var parentScale = parent.lossyScale;
            transform.localScale = new Vector3(scale * parentScale.x,scale * parentScale.y,scale * parentScale.z);
            transform.SetParent(parent);
            transform.localPosition = Vector3.zero;
            transform.localEulerAngles = Vector3.zero;
        }
        
        public static void SetTransformData(Transform transform, Vector3 position, Vector3 forward, float scale)
        {
            transform.localScale = new Vector3(scale,scale,scale);
            transform.position = position;
            transform.forward = forward;
        }
        
        public static void SetTransformDataXYZ(Transform transform, float p1,float p2,float p3, float f1,float f2, float f3, float scale)
        {
            transform.localScale = new Vector3(scale,scale,scale);
            transform.position = new Vector3(p1,p2,p3);
            transform.forward = new Vector3(f1,f2,f3);
        }

        public static void SetTransformDataAndLayer(Transform transform,Vector3 position,Vector3 forward,float scale,int layer)
        {
            transform.localScale = new Vector3(scale,scale,scale);
            transform.position = position;
            transform.forward = forward;
            transform.gameObject.SetLayerRecursively(layer);
        }

        public static void PlayBossTimeline(PlayableDirector director, CinemachineBrain brain,
            CinemachineVirtualCamera origin, CinemachineVirtualCamera bossCom, CinemachineVirtualCamera after,
            Transform followTarget)
        {
            var asset = director.playableAsset;
            CinemachineTrack cameraTrack = null;
            foreach (var bind in asset.outputs)
            {
                if (bind.outputTargetType == typeof(CinemachineBrain))
                {
                    cameraTrack = bind.sourceObject as CinemachineTrack;
                }
            }

            if (cameraTrack != null)
            {
                director.SetGenericBinding(cameraTrack, brain);
                int index = 0;
                foreach (var clip in cameraTrack.GetClips())
                {
                    if (clip.asset is CinemachineShot shot)
                    {
                        if (clip.displayName == "origin")
                        {
                            shot.VirtualCamera = new ExposedReference<CinemachineVirtualCameraBase>
                            {
                                defaultValue = origin,
                            };
                        }
                        else if (clip.displayName == "bossCome")
                        {
                            shot.VirtualCamera = new ExposedReference<CinemachineVirtualCameraBase>
                            {
                                defaultValue = bossCom,
                            };
                            bossCom.Follow = followTarget;
                            bossCom.LookAt = followTarget;
                            bossCom.enabled = true;
                        }
                        else if (clip.displayName == "after")
                        {
                            shot.VirtualCamera = new ExposedReference<CinemachineVirtualCameraBase>
                            {
                                defaultValue = after,
                            };
                        }
                    }
                }
            }
            director.time = 0;
            director.Play();
        }

        public static void SetModuleContainerLoadedCallback(Transform transform,LuaFunction function)
        {
            var moduleContainer = transform.GetComponent<YModuleContainer>();
            if (moduleContainer)
            {
                moduleContainer.onPrefabLoaded += (o) => { function.Action(o); };
            }
        }

        public static void SetScreenShoot(UIExpansion uiExpansion,YImage image)
        {
            uiExpansion.StartCoroutine(GetScreenShot(image));
        }
        
        private static IEnumerator GetScreenShot(YImage image)
        {
            yield return new WaitForEndOfFrame();
            var rectTransform = image.rectTransform;
            var rect = new Rect(0,0,Screen.width,Screen.height);
            var screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
            screenShot.ReadPixels(rect,0,0);
            screenShot.Apply();
            image.sprite = Sprite.Create(screenShot, rect, new Vector2(0.5f,0.5f));
        }

        public static void SetAnimationSpeed(Animation animation,float speed)
        {
            if (animation != null)
            {
                foreach (AnimationState state in animation)
                {
                    state.speed = speed;
                }
            }
        }
    }
}
